import { Icon } from '@iconify/vue'
import type { InternalRuleItem } from 'async-validator'
import {
  ElButton,
  ElCard,
  ElCol,
  ElForm,
  ElFormItem,
  ElInput,
  ElRadio,
  ElRadioGroup,
  ElRow,
  ElTabPane,
  ElTabs,
  type FormInstance,
  type FormRules
} from 'element-plus'
import { defineComponent, onBeforeMount, reactive, toRefs } from 'vue'
import { useRoute, useRouter } from 'vue-router'

import {
  currentUserApi,
  dictApi,
  type IGetUserProfileRes,
  type IUpdateUserBaseReq,
  type IUpdateUserPasswordReq
} from '@/apis'
import { useUserStore } from '@/store'
import {
  dictToOptions,
  fmtDate,
  getElementFnFromInstance,
  isEmail,
  isPhoneNumber,
  objAssign
} from '@/utils'
import { bus } from '@/utils'

import styles from './index.module.css'

export default defineComponent({
  name: 'UserCenterIndexView',
  setup() {
    const state = reactive({
      userProfile: {} as IGetUserProfileRes,
      activeTab: '0',
      baseFormRef: {} as FormInstance,
      baseFormModel: {
        nickName: '',
        phone: '',
        email: '',
        sex: '0'
      } as IUpdateUserBaseReq,
      baseFormRules: {
        nickName: [{ required: true, message: '用户昵称不能为空' }],
        phone: [
          { required: true, message: '手机号码不能为空' },
          { validator: phoneValidator }
        ],
        email: [
          { required: true, message: '邮箱地址不能为空' },
          { validator: emailValidator }
        ]
      } as FormRules<IUpdateUserBaseReq>,
      passwordFormRef: {} as FormInstance,
      passwordFormModel: {
        oldPassword: '',
        newPassword: '',
        confirmPassword: ''
      } as IUpdateUserPasswordReq,
      passwordFormRules: {
        oldPassword: [{ required: true, message: '旧密码不能为空' }],
        newPassword: [{ required: true, message: '新密码不能为空' }],
        confirmPassword: [
          { required: true, message: '确认密码不能为空' },
          { validator: confirmPasswordValidator }
        ]
      } as FormRules<IUpdateUserPasswordReq>,
      sexOptions: [] as OptionItem[],
      confirmLoading: false
    })

    const route = useRoute()
    const router = useRouter()
    const { $notify } = getElementFnFromInstance()
    const userStore = useUserStore()

    function emailValidator(
      rule: InternalRuleItem,
      value: any,
      callback: (error?: string | Error | undefined) => void
    ) {
      if (isEmail(value)) {
        callback()
      } else {
        callback(new Error('请输入正确的邮箱地址'))
      }
    }

    function phoneValidator(
      rule: InternalRuleItem,
      value: any,
      callback: (error?: string | Error | undefined) => void
    ) {
      if (isPhoneNumber(value)) {
        callback()
      } else {
        callback(new Error('请输入正确的手机号码'))
      }
    }

    function confirmPasswordValidator(
      rule: InternalRuleItem,
      value: any,
      callback: (error?: string | Error | undefined) => void
    ) {
      if (value !== state.passwordFormModel.newPassword) {
        callback(new Error('两次输入的密码不一致'))
      } else {
        callback()
      }
    }

    async function init() {
      const [userProfile, dictSex] = await Promise.all([
        await currentUserApi.getProfile(),
        dictApi.getDictDataList('sys_user_sex')
      ])

      state.userProfile = userProfile
      state.sexOptions = dictToOptions(dictSex)
      objAssign(state.baseFormModel, userProfile)
    }

    function handleSaveBaseForm() {
      state.baseFormRef.validate(async valid => {
        if (valid) {
          try {
            state.confirmLoading = true
            await currentUserApi.updateBase(state.baseFormModel)
            $notify.success({
              title: '提示',
              message: '更新用户基本信息成功',
              duration: 1500
            })
          } finally {
            state.confirmLoading = false
          }
        }
      })
    }

    function handleSavePasswordForm() {
      state.passwordFormRef.validate(async valid => {
        if (valid) {
          try {
            state.confirmLoading = true
            await currentUserApi.updatePassword(state.passwordFormModel)
            $notify.success({
              title: '提示',
              message: '更新用户密码成功，将重新登录',
              duration: 1500,
              onClose: async () => {
                await userStore.logout()
                router.replace({ path: '/login' })
              }
            })
          } finally {
            state.confirmLoading = false
          }
        }
      })
    }

    function handleClose() {
      bus.emit('handleCloseTab', route)
    }

    onBeforeMount(() => {
      init()
    })

    return {
      ...toRefs(state),
      fmtDate,
      handleSaveBaseForm,
      handleSavePasswordForm,
      handleClose
    }
  },
  render() {
    return (
      <div class={styles.view}>
        <ElRow gutter={15}>
          <ElCol span={6}>
            <ElCard>
              {{
                header: () => (
                  <div>
                    <span>个人信息</span>
                  </div>
                ),
                default: () => (
                  <div class={styles.list}>
                    <div class={styles.listItem}>
                      <div class={styles.left}>
                        <Icon
                          icon="@local:icon-park-outline:user"
                          inline={true}
                        />
                        <span>用户名称</span>
                      </div>
                      <div class={styles.right}>
                        <span>{this.userProfile.nickName}</span>
                      </div>
                    </div>
                    <div class={styles.listItem}>
                      <div class={styles.left}>
                        <Icon
                          icon="@local:icon-park-outline:phone"
                          inline={true}
                        />
                        <span>手机号码</span>
                      </div>
                      <div class={styles.right}>
                        <span>{this.userProfile.phone}</span>
                      </div>
                    </div>
                    <div class={styles.listItem}>
                      <div class={styles.left}>
                        <Icon
                          icon="@local:icon-park-outline:mail"
                          inline={true}
                        />
                        <span>用户邮箱</span>
                      </div>
                      <div class={styles.right}>{this.userProfile.email}</div>
                    </div>
                    <div class={styles.listItem}>
                      <div class={styles.left}>
                        <Icon
                          icon="@local:icon-park-outline:every-user"
                          inline={true}
                        />
                        <span>所属部门</span>
                      </div>
                      <div class={styles.right}>
                        <span>
                          {this.userProfile.deptName}/
                          {this.userProfile.postGroup}
                        </span>
                      </div>
                    </div>
                    <div class={styles.listItem}>
                      <div class={styles.left}>
                        <Icon
                          icon="@local:icon-park-outline:permissions"
                          inline={true}
                        />
                        <span>所属角色</span>
                      </div>
                      <div class={styles.right}>
                        <span>{this.userProfile.roleGroup}</span>
                      </div>
                    </div>
                    <div class={styles.listItem}>
                      <div class={styles.left}>
                        <Icon
                          icon="@local:icon-park-outline:calendar"
                          inline={true}
                        />
                        <span>创建日期</span>
                      </div>
                      <div class={styles.right}>
                        <span>{this.fmtDate(this.userProfile.createTime)}</span>
                      </div>
                    </div>
                  </div>
                )
              }}
            </ElCard>
          </ElCol>
          <ElCol span={18}>
            <ElCard>
              {{
                header: () => (
                  <div>
                    <span>基本资料</span>
                  </div>
                ),
                default: () => (
                  <ElTabs>
                    <ElTabPane label="基本资料" name="0">
                      <ElForm
                        ref={(e: any) => (this.baseFormRef = e)}
                        model={this.baseFormModel}
                        rules={this.baseFormRules}
                        labelWidth="80px"
                      >
                        <ElFormItem label="用户昵称" prop="nickName">
                          <ElInput v-model={this.baseFormModel.nickName} />
                        </ElFormItem>
                        <ElFormItem label="手机号码" prop="phone">
                          <ElInput v-model={this.baseFormModel.phone} />
                        </ElFormItem>
                        <ElFormItem label="邮箱" prop="email">
                          <ElInput v-model={this.baseFormModel.email} />
                        </ElFormItem>
                        <ElFormItem label="性别" prop="sex">
                          <ElRadioGroup v-model={this.baseFormModel.sex}>
                            {this.sexOptions.map(item => (
                              <ElRadio key={item.value} value={item.value}>
                                {item.label}
                              </ElRadio>
                            ))}
                          </ElRadioGroup>
                        </ElFormItem>
                        <ElFormItem>
                          <ElButton
                            loading={this.confirmLoading}
                            type="primary"
                            onClick={this.handleSaveBaseForm}
                          >
                            保存
                          </ElButton>
                          <ElButton type="danger" onClick={this.handleClose}>
                            关闭
                          </ElButton>
                        </ElFormItem>
                      </ElForm>
                    </ElTabPane>
                    <ElTabPane label="修改密码" name="1">
                      <ElForm
                        ref={(e: any) => (this.passwordFormRef = e)}
                        model={this.passwordFormModel}
                        rules={this.passwordFormRules}
                        labelWidth="80px"
                      >
                        <ElFormItem label="旧密码" prop="oldPassword">
                          <ElInput
                            v-model={this.passwordFormModel.oldPassword}
                            type="password"
                            placeholder="请输入旧密码"
                          />
                        </ElFormItem>
                        <ElFormItem label="新密码" prop="newPassword">
                          <ElInput
                            v-model={this.passwordFormModel.newPassword}
                            type="password"
                            placeholder="请输入新密码"
                          />
                        </ElFormItem>
                        <ElFormItem label="确认密码" prop="confirmPassword">
                          <ElInput
                            v-model={this.passwordFormModel.confirmPassword}
                            type="password"
                            placeholder="请输入新密码"
                          />
                        </ElFormItem>
                        <ElFormItem>
                          <ElButton
                            loading={this.confirmLoading}
                            type="primary"
                            onClick={this.handleSavePasswordForm}
                          >
                            保存
                          </ElButton>
                          <ElButton type="danger" onClick={this.handleClose}>
                            关闭
                          </ElButton>
                        </ElFormItem>
                      </ElForm>
                    </ElTabPane>
                  </ElTabs>
                )
              }}
            </ElCard>
          </ElCol>
        </ElRow>
      </div>
    )
  }
})
